package com.rabbit.icore;

import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

/**
 * 共享变量管理库
 * 主要用于解决【指定的】多个线程安全地共享一个变量，而其它线程无法共享，也可以存redis
 */
public class AppContext {
    //回调函数结果：Result管理仓库，每个发布都对应一个result，一个主线程，二个回调的子线程共享这个result，执行完后消除
    private static HashMap<String, Result> resultMap = new HashMap<>();
    //countDownLatch管理仓库，每个发布消息请求有两个回调：confirmCallback和returnCallback，但第二个成功时就不会执行所以很难得到结果，所以这里并没有使用
    //每个回调线程和主线程分别共享各自的CountDownLatch，这个主键可以由appId+tenantId+回调类型来区分。
    private static HashMap<String, CountDownLatch> countDownLatchMap = new HashMap<>();
    //发布失败后执行次数的计数器，需要每个线程单独使用
    private static ThreadLocal<Integer> count = ThreadLocal.withInitial(() -> new Integer(0));
    public static String confirmCall = "confirm";
    public static String returnCall = "return";


    //==============================Result=====================================

    /**
     * 主线程获取到了自己的result结果，删除自己的result，避免内存泄漏导致内存溢出
     *
     * @param resultName
     */

    private static void deleteResult(String resultName) {
        resultMap.remove(resultName);
    }


    /**
     * 主线程获取result结果
     *
     * @param resultName
     * @return
     */
    public static Result getResult(String resultName) {
        Result result = resultMap.get(resultName);
        deleteResult(resultName);
        return result;
    }

    /**
     * 子线程设置值
     *
     * @param resultName
     * @param key
     * @param value
     * @return
     */
    public static void setResult(String resultName, String key, String value) {
        Result result = new Result();
        result.put(key, value);
        resultMap.put(resultName, result);
    }

    //========================================countDownLaunch=======================================================

    /**
     * 主线程进行对自己子线程地专属等待
     *
     * @param countDownLatchName
     */
    public static void await(String countDownLatchName) {
        CountDownLatch countDownLatch = countDownLatchMap.get(countDownLatchName);
        if (countDownLatch == null) {
            countDownLatch = new CountDownLatch(1);
            countDownLatchMap.put(countDownLatchName, countDownLatch);
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 主线程等待结束，删除专属的countDownLatch，对象避免内存泄漏导致内存溢出
     *
     * @param countDownLatchName
     */
    public static void deleteCountDownLatch(String countDownLatchName) {
        countDownLatchMap.remove(countDownLatchName);
    }

    /**
     * 子线程调用，告知主线程自己执行完毕
     *
     * @param countDownLatchName
     */

    public static void countDown(String countDownLatchName) {
        CountDownLatch countDownLatch = countDownLatchMap.get(countDownLatchName);
        if (countDownLatch == null) {
            countDownLatch = new CountDownLatch(1);
            countDownLatchMap.put(countDownLatchName, countDownLatch);
        }
        countDownLatch.countDown();
    }


//    ============================================count值===============================================================

    //获取count的值
    public static int getCount() {
        return count.get();
    }

    //count++
    public static void countUp() {
        count.set(count.get() + 1);
    }

    //设置count
    public static void setCount(int i) {
        count.set(0);
    }

    //remove

}
